home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 9 / Night Owl CD-ROM (NOPV9) (Night Owl Publisher) (1993).ISO / 009a / snpd0493.zip / TAIL.C < prev    next >
C/C++ Source or Header  |  1993-04-05  |  5KB  |  188 lines

  1. .I 0 8
  2. /*
  3. **  TAIL.C  Display the last "n" lines of a file (5 lines by default).
  4. **  Written February 4, 1986 by Joe Huffman
  5. **  Modified October 5, 1986 by Joe Huffman
  6. **    Utilize prototyping, fixed a bug, added (a few) comments and help.
  7. **
  8. **  Not copyrighted.
  9. */ 
  10. .D 1 14
  11. .I 16 2
  12. #include <stdlib.h>
  13. #include <string.h>
  14. .I 24 80
  15. void getlinenum (int n, unsigned char *str[]);
  16. void gettail (void);
  17. void LtoA (long int val, unsigned char *cp);
  18.  
  19. main (int argc, unsigned char *argv[])
  20. {
  21.       if (argc <= 1)
  22.       {
  23.             help ();
  24.             return (1);
  25.       }
  26.  
  27.       getlinenum (argc, argv);
  28.  
  29.       for (filenum = 1; filenum < argc; ++filenum)
  30.       {
  31.             if (*argv[filenum] == '/')
  32.                   continue;
  33.             fp = fopen (argv[filenum], "rb");
  34.             if (!fp)
  35.             {
  36.                   fputs (head1, stderr);
  37.                   fputs (argv[filenum], stderr);
  38.                   fputs ("\" not found.", stderr);
  39.                   fputs (head2, stderr);
  40.             }
  41.             else
  42.             {
  43.                   fputs (head1, stdout);
  44.                   fputs (argv[filenum], stdout);
  45.                   gettail ();
  46.                   fputs (head2, stdout);
  47.                   for (cc = getc (fp); cc != EOF; cc = getc (fp))
  48.                         fputc (cc, stdout);
  49.                   fclose (fp);
  50.             }
  51.       }
  52. }
  53.  
  54. /*
  55. **  Get the number of lines to display at the "tail" of each file from
  56. **  the command line.
  57. */
  58.  
  59. void getlinenum (int n, unsigned char *str[])
  60. {
  61.       for (--n; n; --n)
  62.       {
  63.             ++str;
  64.             if (**str == '/')
  65.             {
  66.                   linenum = atoi (*(str) + 1);
  67.                   if (linenum <= 0)
  68.                         linenum = 5;
  69.             }
  70.       }
  71.       linenum++;
  72.       /* Because we save a pointer to the end of the PREVIOUS line. */
  73. }
  74.  
  75. /*
  76. **  Set the file pointer "fp" to "linenum - 1" lines before the end of
  77. **  the file.
  78. */
  79.  
  80. void gettail (void)
  81. {
  82.       unsigned char outstr[15];
  83.       void *malloc (unsigned int);
  84.       unsigned long int currline = 0L;
  85.  
  86.       tail = (long int *)malloc (sizeof(*tail) * linenum);
  87.       if (!tail)
  88.       {
  89.             fputs ("Insufficient memory.", stderr);
  90.             exit (1);
  91.       }
  92.       tail[0] = ftell (fp);
  93.       indx = 0;
  94.  
  95. .D 25 31
  96. .I 56 90
  97.       {
  98.             if (cc == '\r')
  99.             {
  100.                   ++currline;
  101.                   cc = getc (fp);
  102.                   if (cc != '\n')
  103.                         ungetc (cc, fp);
  104.                   ++indx;
  105.                   indx %= linenum;
  106.                   tail[indx] = ftell (fp);
  107.             }
  108.             else
  109.             {
  110.                   if (cc == '\n')
  111.                   {
  112.                         ++currline;
  113.                         cc = getc (fp);
  114.                         if (cc != '\r')
  115.                               ungetc (cc, fp);
  116.                         ++indx;
  117.                         indx %= linenum;
  118.                         tail[indx] = ftell (fp);
  119.                   }
  120.             }
  121.       }
  122.       fputs ("\" ", stdout);
  123.       LtoA (currline, outstr);
  124.       fputs (outstr, stdout);
  125.       fputs (" lines", stdout);
  126.       if (currline >= linenum - 1)
  127.       {
  128.             indx++;
  129.             indx %= linenum;
  130.       }
  131.       else  indx = 0;
  132.  
  133.       if (fseek (fp, tail[indx], 0) == -1)
  134.       {
  135.             fputs ("\nFile seek error.", stderr);
  136.             exit (1);
  137.       }
  138.       free (tail);
  139. }
  140.  
  141. /*
  142. **  long integer to ASCII.  Use this function rather than the ltoa()
  143. **  library function to save many bytes in the executable file.
  144. */
  145.  
  146. void LtoA (long int val, unsigned char *cp)
  147. {
  148.       unsigned char tempc[15], *tcptr;
  149.       int sign;
  150.       static unsigned char dig[] = {"0123456789"};
  151.  
  152.       if (val < 0)
  153.       {
  154.             val = -val;
  155.             sign = 1;
  156.       }
  157.       else  sign = 0;
  158.  
  159.       *(tcptr = tempc + 11) = '\0';
  160.       do 
  161.       {
  162.             *--tcptr = dig[(int)(val % 10)];
  163.       }while (val /= 10);
  164.       if (sign)
  165.             *--tcptr = '-';
  166.       strcpy (cp, tcptr);
  167. }
  168.  
  169. /*
  170. **  Tell the user what the program is and how to use it.
  171. */
  172.  
  173. void help (void)
  174. {
  175.       char *ptr;
  176.       static char help_str[] = { "Command error: No file(s) specified.\n"
  177.             "Written by Joe Huffman.\n"
  178.             "TAIL is a program that prints out only the last lines of a "
  179.             "program.\nusage:\nTAIL filename [filename] [/n]\n\n"
  180.             "filename - The name of a valid file, wildcards accepted.\n"
  181.             "n - number of lines to print out, 5 by default."
  182.             };
  183.  
  184.       for (ptr = &help_str[0]; *ptr; ptr++)
  185.             fputc (*ptr, stdout);
  186. }
  187. .D 57 139
  188.